package com.czy.utils;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.czy.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Map;

/**
 * Http请求工具类
 * @author czy
 * @date 2020-9-1
 */
@Slf4j
public class HttpUtils {
    /**
     * 创建HttpClient
     * @return
     */
    public static CloseableHttpClient createHttpClient(){
        RequestConfig reqConf = RequestConfig.custom().setConnectTimeout(10000).setSocketTimeout(30000).build();
        HttpClientBuilder builder = HttpClients.custom();
        builder.setDefaultRequestConfig(reqConf);
        return builder.build();
    }

    /**
     * post请求
     * @param url 请求地址
     * @param body 请求体
     * @param headerMap 请求头
     * @return
     */
    public static HttpResponse doPost(String url, Object body, Map<String,String> headerMap) {
        String requestBody = JSON.toJSONString(body);
        log.debug("POST请求地址: {},请求体内容: {}, 请求头内容: {}",url,requestBody, JSON.toJSONString(headerMap));
        HttpResponse response = HttpRequest.post(url).setConnectionTimeout(10000)
                .addHeaders(headerMap)
                .body(requestBody)
                .execute();
        log.debug("响应状态码: {}, 响应体内容: {}",response.getStatus(),response.body());
        return response;
    }

    /**
     * 文件上传
     * @param url
     * @param multipartFile
     * @param headerMap
     * @return
     */
    public static HttpResponse fileUpload(String url,MultipartFile multipartFile, Map<String,String> headerMap){
        InputStream inputStream=null;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException("获取文件流失败");
        }
        InputStreamResource resource = new InputStreamResource(inputStream,multipartFile.getName());
        log.debug("POST请求地址: {}, 请求头内容: {}",url, JSON.toJSONString(headerMap));
        HttpResponse response=HttpRequest.post(url).form("file",resource).setConnectionTimeout(10000)
                .addHeaders(headerMap)
                .execute();
        log.debug("响应状态码: {}, 响应体内容: {}",response.getStatus(),response.body());
        return response;
    }

    /**
     * post请求
     * @param url 请求地址
     * @param body 请求体
     * @param headerMap 请求头
     * @param connectionTimeout 请求连接时间
     * @param readTimeOut 读取时间
     * @return
     */
    public static HttpResponse doPost(String url, Object body, Map<String,String> headerMap,
                                      int connectionTimeout,int readTimeOut) {
        String requestBody = JSON.toJSONString(body);
        log.debug("POST请求地址: {},请求体内容: {}, 请求头内容: {}",url,requestBody, JSON.toJSONString(headerMap));
        HttpResponse response = HttpRequest.post(url)
                .setConnectionTimeout(connectionTimeout)
                .setReadTimeout(readTimeOut)
                .addHeaders(headerMap)
                .body(requestBody)
                .execute();
        log.debug("响应状态码: {}, 响应体内容: {}",response.getStatus(),response.body());
        return response;
    }

    /**
     * get请求
     * @param url
     * @return
     */
    public static HttpResponse doGet(String url,Map<String,String> headerMap) {
        log.debug("GET请求地址: {}, 请求头内容: {}",url, JSON.toJSONString(headerMap));
        HttpResponse response = HttpRequest.get(url).addHeaders(headerMap).timeout(10000).execute();
        log.debug("响应状态码: {}, 响应体内容: {}",response.getStatus(),response.body());
        return response;
    }

    /**
     * get请求
     * @param url   请求地址
     * @param headerMap 请求头
     * @param connectionTimeout 连接超时
     * @param readTimeOut   读取超时
     * @return
     */
    public static HttpResponse doGet(String url,Map<String,String> headerMap,int connectionTimeout,int readTimeOut) {
        log.debug("GET请求地址: {}, 请求头内容: {}",url, JSON.toJSONString(headerMap));
        HttpResponse response = HttpRequest.get(url).addHeaders(headerMap)
                .setConnectionTimeout(connectionTimeout)
                .setReadTimeout(readTimeOut)
                .execute();
        log.debug("响应状态码: {}, 响应体内容: {}",response.getStatus(),response.body());
        return response;
    }

    /**
     * 文件下载
     * @param fileName
     * @param inputStream
     * @param response
     * @return
     */
    public static void downFile(String fileName, InputStream inputStream, HttpServletResponse response){
        try {
            // 设置输出的格式
//            response.reset();
            response.setContentType("application/octet-stream");
            response.setHeader("Cache-Control","no-cache");
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            BufferedOutputStream bufferOutputStream = new BufferedOutputStream(response.getOutputStream());
            //一次读取8kb
            byte[] b = new byte[1024*8];
            int len;
            // 循环取出流中的数据
            while ((len = bufferedInputStream.read(b)) > 0){
                bufferOutputStream.write(b, 0, len);
            }
            bufferOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
